package util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * JDBC数据库工具类
 * 目前数据库连接资源部分，已经替换为Druid数据库连接池。
 *      1. 数据库对象获取功能
 *      2. 数据库资源关闭功能
 */
public class JdbcUtil {
    /**
     * java.sql.DataSource 数据库连接池对象。
     */
    private static DataSource ds;

    static {
        try {
            // 加载src 目录下 druid.properties文件当前Properties对象中
            Properties properties = new Properties();
            properties.load(JdbcUtil.class.getClassLoader().getResourceAsStream("druid.properties"));

            // 使用DruidDataSourceFactory Druid数据库连接池工厂类，调用创建数据库连接池方法，传入参数是Properties类对象
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接池对象
     *
     * @return java.sql.DataSource 数据库连接池对象
     */
    public static DataSource getDataSource() {
        return ds;
    }


    /**
     * JDBC工具类获取数据连接对象方法。如果用户提供的数据库连接信息有误，返回null
     *
     * @return java.sql.Connection对象，如果信息有误，返回null
     */
    public static Connection getConnection() {
        Connection connection = null;

        try {
            // 从数据库连接池中获取当前闲置数据库连接对象
            connection =  ds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }

    /**
     * 对外提供关闭数据库连接对象方法
     *
     * @param conn java.sql.Connection数据库连接对象
     */
    public static void close(Connection conn) {
        close(conn, null, null);
    }

    /**
     * 对外提供关闭数据库和数据库表搬运工对象方法
     *
     * @param conn java.sql.Connection 数据库连接对象
     * @param st   java.sql.Statement 数据库搬运工对象
     */
    public static void close(Connection conn, Statement st) {
        close(conn, st, null);
    }

    /**
     * 对外提供关闭数据库,数据库表搬运工对象以及数据库查询结果集对象方法
     *
     * @param conn java.sql.Connection 数据库连接对象
     * @param st   java.sql.Statement 数据库搬运工对象
     * @param rs   java.sql.ResultSet 数据库查询结果集对象
     */
    public static void close(Connection conn, Statement st, ResultSet rs) {
        try {
            close(rs, st, conn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 类内私有化静态成员方法，用于提供关闭资源的一个能力
     *
     * @param res AutoCloseable 接口不定长参数，要求传入的是当前数据库操作对应的数据库资源
     * @throws Exception AutoCloseable 接口中close方法抛出异常
     */
    private static void close(AutoCloseable... res) throws Exception {
        for (AutoCloseable re : res) {
            if (re != null) {
                re.close();
            }
        }
    }
}
